/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GPIO_DRV_H
#define GPIO_DRV_H

/*!
 * @file gpio_drv.h
 * @brief This file declares gpio driver interfaces
 */

/*!
 * @addtogroup gpio_drv
 * @{
 */

/*******Includes***************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "device_registers.h"

/*******Definitions************************************************************/

/*!
 * @brief GPIO pin mask, for GPIO port write
 */
#define GPIO_PIN0_MSK       (0x00000001UL)   /*!< GPIO pin0 mask */
#define GPIO_PIN1_MSK       (0x00000002UL)   /*!< GPIO pin1 mask */
#define GPIO_PIN2_MSK       (0x00000004UL)   /*!< GPIO pin2 mask */
#define GPIO_PIN3_MSK       (0x00000008UL)   /*!< GPIO pin3 mask */
#define GPIO_PIN4_MSK       (0x00000010UL)   /*!< GPIO pin4 mask */
#define GPIO_PIN5_MSK       (0x00000020UL)   /*!< GPIO pin5 mask */
#define GPIO_PIN6_MSK       (0x00000040UL)   /*!< GPIO pin6 mask */
#define GPIO_PIN7_MSK       (0x00000080UL)   /*!< GPIO pin7 mask */
#define GPIO_PIN8_MSK       (0x00000100UL)   /*!< GPIO pin8 mask */
#define GPIO_PIN9_MSK       (0x00000200UL)   /*!< GPIO pin9 mask */
#define GPIO_PIN10_MSK      (0x00000400UL)   /*!< GPIO pin10 mask */
#define GPIO_PIN11_MSK      (0x00000800UL)   /*!< GPIO pin11 mask */
#define GPIO_PIN12_MSK      (0x00001000UL)   /*!< GPIO pin12 mask */
#define GPIO_PIN13_MSK      (0x00002000UL)   /*!< GPIO pin13 mask */
#define GPIO_PIN14_MSK      (0x00004000UL)   /*!< GPIO pin14 mask */
#define GPIO_PIN15_MSK      (0x00008000UL)   /*!< GPIO pin15 mask */
#define GPIO_PIN16_MSK      (0x00010000UL)   /*!< GPIO pin16 mask */
#define GPIO_PIN17_MSK      (0x00020000UL)   /*!< GPIO pin17 mask */
#define GPIO_PIN18_MSK      (0x00040000UL)   /*!< GPIO pin18 mask */
#define GPIO_PIN19_MSK      (0x00080000UL)   /*!< GPIO pin19 mask */
#define GPIO_PIN20_MSK      (0x00100000UL)   /*!< GPIO pin20 mask */
#define GPIO_PIN21_MSK      (0x00200000UL)   /*!< GPIO pin21 mask */
#define GPIO_PIN22_MSK      (0x00400000UL)   /*!< GPIO pin22 mask */
#define GPIO_PIN23_MSK      (0x00800000UL)   /*!< GPIO pin23 mask */
#define GPIO_PIN24_MSK      (0x01000000UL)   /*!< GPIO pin24 mask */
#define GPIO_PIN25_MSK      (0x02000000UL)   /*!< GPIO pin25 mask */
#define GPIO_PIN26_MSK      (0x04000000UL)   /*!< GPIO pin26 mask */
#define GPIO_PIN27_MSK      (0x08000000UL)   /*!< GPIO pin27 mask */
#define GPIO_PIN28_MSK      (0x10000000UL)   /*!< GPIO pin28 mask */
#define GPIO_PIN29_MSK      (0x20000000UL)   /*!< GPIO pin29 mask */
#define GPIO_PIN30_MSK      (0x40000000UL)   /*!< GPIO pin30 mask */
#define GPIO_PIN31_MSK      (0x80000000UL)   /*!< GPIO pin31 mask */

#define GPIO_PIN_MSK(pin)   (1UL << pin)     /*!< GPIO pin mask */

/*!
 * @brief Configures the GPIO pin level
 */
typedef enum {
    GPIO_PIN_LEVEL_LOW    = 0U,    /*!< Pin level low */
    GPIO_PIN_LEVEL_HIGH   = 1U     /*!< Pin level high */
} gpio_pin_level_t;

/*!
 * @brief Configures the GPIO pin mode
 */
typedef enum {
    GPIO_PIN_MODE_HIZ       = 0U,    /*!< High impedance */
    GPIO_PIN_MODE_OUTPUT    = 1U,    /*!< General purpose output */
    GPIO_PIN_MODE_INPUT     = 2U,    /*!< General purpose input */
    GPIO_PIN_MODE_BI_OUTPUT = 3U     /*!< General purpose bidirectional output(input and output) */
} gpio_pin_mode_t;

/*!
 * @brief Configures internal resistor pull feature
 */
typedef enum {
    GPIO_PIN_PULL_FLOATING  = 0U,    /*!< Internal pull-down and pull-up resistor is not enabled */
    GPIO_PIN_PULL_UP        = 1U,    /*!< Internal pull-up resistor is enabled */
    GPIO_PIN_PULL_DOWN      = 2U     /*!< Internal pull-down resistor is enabled */
} gpio_pin_pull_t;

/*!
 * @brief Configures the drive strength
 */
typedef enum {
    GPIO_PIN_DRV_5MA    = 0U,    /*!< 5mA  drive strength is configured */
    GPIO_PIN_DRV_20MA   = 1U     /*!< 20mA drive strength is configured */
} gpio_pin_drv_t;

/*!
 * @brief Configures the slew rate
 */
typedef enum {
    GPIO_PIN_SLEW_RATE_FAST = 0U,    /*!< Fast slew rate */
    GPIO_PIN_SLEW_RATE_SLOW = 1U     /*!< Slow slew rate */
} gpio_pin_slew_rate_t;

/*!
 * @brief Configures the Pin mux function
 */
typedef enum {
    GPIO_PIN_MUX_DISABLED   = 0U,    /*!< Pin is disabled(HiZ), but it can be used as an analog pin still */
    GPIO_PIN_MUX_GPIO       = 1U,    /*!< Pin is configured as GPIO */
    GPIO_PIN_MUX_FUN2       = 2U,    /*!< See PIN_MUX table */
    GPIO_PIN_MUX_FUN3       = 3U,    /*!< See PIN_MUX table */
    GPIO_PIN_MUX_FUN4       = 4U,    /*!< See PIN_MUX table */
    GPIO_PIN_MUX_FUN5       = 5U,    /*!< See PIN_MUX table */
    GPIO_PIN_MUX_FUN6       = 6U,    /*!< See PIN_MUX table */
    GPIO_PIN_MUX_FUN7       = 7U     /*!< See PIN_MUX table */
} gpio_pin_mux_t;

/*!
 * @brief Configures the interrupt generation condition
 */
typedef enum {
    GPIO_PIN_INT_DISABLED       = 0U, /*!< External interrupt request is disabled */
    GPIO_PIN_INT_RISING_EDGE    = 1U, /*!< External interrupt on rising edge */
    GPIO_PIN_INT_FALLING_EDGE   = 2U, /*!< External interrupt on falling edge */
    GPIO_PIN_INT_BOTH_EDGE      = 3U  /*!< External interrupt on both edge */
} gpio_pin_int_t;

/*!
 * @brief Configures the GPIO pin structure
 */
typedef struct {
    GPIO_Type* base;                /*!< GPIO base pointer */
    uint32_t   pin;                 /*!< GPIO pin number */
    gpio_pin_mux_t mux;             /*!< GPIO pin mux function */
    gpio_pin_mode_t pinMode;        /*!< Configures the pin mode */
    gpio_pin_pull_t pullConfig;     /*!< Internal resistor pull feature selection */
    gpio_pin_int_t  intConfig;      /*!< External interrupt generation condition,
                                         The user need to call NVIC_EnableIRQ() to enable GPIO interrupt vector */
    gpio_pin_slew_rate_t slewRate;  /*!< Configures the slew rate */
    gpio_pin_drv_t driveStrength;   /*!< Configures the drive strength */
    bool digitalFilterRUN;          /*!< Enables digital filter in RUN mode, false:Disabled true: Enabled  */
    bool pinLock;                   /*!< Lock pin control register or not, false:not Locked true: Locked */
    gpio_pin_level_t initLevel;     /*!< Pin initial level */
} gpio_pin_config_t;

/*******APIs*******************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Initializes the pins with the options provided in the structure
 *
 * @param[in] pinCount: The total number of configured pins in structure
 * @param[in] gpioConfig: The configuration structure
 * @return None
 */
void GPIO_Init(uint8_t pinCount,
               const gpio_pin_config_t* gpioConfig);

/*!
 * @brief Configure the mode for the given pin with the given mode
 *
 * @param[in] regBase: GPIO base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] pinMode: The pin mode, HiZ or Input or Output
 *        - GPIO_PIN_MODE_HIZ: corresponding pin is set to Hiz
 *        - GPIO_PIN_MODE_INPUT: corresponding pin is set to input
 *        - GPIO_PIN_MODE_OUTPUT: corresponding pin is set to output
 *        - GPIO_PIN_MODE_BI_OUTPUT: corresponding pin is set to bidirectional output(input and output)
 * @return None
 */
void GPIO_SetPinMode(GPIO_Type* regBase,
                     uint32_t pinNum,
                     gpio_pin_mode_t pinMode);

/*!
 * @brief Get the pin mode configuration for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return pin mode
 *        - GPIO_PIN_MODE_HIZ: corresponding pin is set to Hiz
 *        - GPIO_PIN_MODE_INPUT: corresponding pin is set to input
 *        - GPIO_PIN_MODE_OUTPUT: corresponding pin is set to output
 *        - GPIO_PIN_MODE_BI_OUTPUT: corresponding pin is set to bidirectional output(input and output)
 */
gpio_pin_mode_t GPIO_GetPinMode(const GPIO_Type* regBase,
                                uint32_t pinNum);

/*!
 * @brief Configures the internal resistor for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] pullConfig: The pull configuration
 *        - GPIO_PIN_PULL_FLOATING: internal pull-down or pull-up resistor is not enabled
 *        - GPIO_PIN_PULL_UP: internal pull-down resistor is enabled
 *        - GPIO_PIN_PULL_DOWN: internal pull-up resistor is enabled
 * @return None
 */
void GPIO_SetPinPull(GPIO_Type* regBase,
                     uint32_t pinNum,
                     gpio_pin_pull_t pullConfig);

/*!
 * @brief Configures the pin lock for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] pinLock: pin lock configration
 *        - true:  Pin lock enabled and pin configration can be changed only after reset
 *        - false: Pin lock disabled and pin configration can be changed anytime
 * @return None
 */
void GPIO_SetPinLock(GPIO_Type* regBase,
                     uint32_t pinNum,
                     bool pinLock);

/*!
 * @brief Configures the pin mux function for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] pinmux: Pin muxing function selection
 *        - GPIO_PIN_DISABLED: Pin disabled
 *        - GPIO_PIN_MUX_GPIO: Set as GPIO
 *        - others           : See PIN_MUX table
 * @return None
 */
void GPIO_SetPinFunc(GPIO_Type* regBase,
                     uint32_t pinNum,
                     gpio_pin_mux_t pinmux);

/*!
 * @brief Configures the pin drive strength for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] driveStrength: Pin drive strength configration
 *        - GPIO_PIN_DRV_5MA:  Pin drive strength set to 5mA
 *        - GPIO_PIN_DRV_20MA: Pin drive strength set to 20mA
 * @return None
 */
void GPIO_SetPinDriveStrength(GPIO_Type* regBase,
                              uint32_t pinNum,
                              gpio_pin_drv_t driveStrength);

/*!
 * @brief Configures the slew rate for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] slewRate: The slew rate configuration
 *        - GPIO_PIN_SLEW_RATE_FAST: Fast slew rate
 *        - GPIO_PIN_SLEW_RATE_SLOW: Slow slew rate
 * @return None
 */
void GPIO_SetPinSlewRate(GPIO_Type* regBase,
                         uint32_t pinNum,
                         gpio_pin_slew_rate_t slewRate);

/*!
 * @brief Configures the GPIO pin external interrupt for the given pin
 *
 * @note  The user need to call NVIC_EnableIRQ() to enable GPIO interrupt vector
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] intConfig: External interrupt configuration
 *        - GPIO_PIN_INT_DISABLED: Interrupt request disabled
 *        - GPIO_PIN_INT_RISING_EDGE: Interrupt on rising edge
 *        - GPIO_PIN_INT_FALLING_EDGE: Interrupt on falling edge
 *        - GPIO_PIN_INT_BOTH_EDGE: Interrupt on either edge
 * @return None
 */
void GPIO_SetPinInt(GPIO_Type* regBase,
                    uint32_t pinNum,
                    gpio_pin_int_t intConfig);

/*!
 * @brief Gets the current GPIO pin external interrupt configuration for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return External interrupt configuration
 *        - GPIO_PIN_INT_DISABLED: Interrupt request disabled
 *        - GPIO_PIN_INT_RISING_EDGE: Interrupt on rising edge
 *        - GPIO_PIN_INT_FALLING_EDGE: Interrupt on falling edge
 *        - GPIO_PIN_INT_BOTH_EDGE: Interrupt on either edge
 */
gpio_pin_int_t GPIO_GetPinInt(const GPIO_Type* regBase,
                              uint32_t pinNum);

/*!
 * @brief Gets the pin external interrupt flag for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return  The pin external interrupt flags
 *         - false: interrupt is not detected
 *         - true: interrupt is detected
 */
bool GPIO_GetPinIntFlag(const GPIO_Type* regBase,
                        uint32_t pinNum);

/*!
 * @brief Clears the individual pin external interrupt flag for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return None
 */
void GPIO_ClearPinIntFlag(GPIO_Type* regBase,
                          uint32_t pinNum);

/*!
 * @brief Gets the entire port external interrupt flag for the given port
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @return All 32 pin external interrupt flags
 * For each bit:
 *         - 0: interrupt is not detected
 *         - 1: interrupt is detected
 */
uint32_t GPIO_GetPortIntFlag(const GPIO_Type* regBase);

/*!
 * @brief Clears the entire port external interrupt flag for the given port
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @return None
 */
void GPIO_ClearPortIntFlag(GPIO_Type* regBase);

/*!
 * @brief Configures digital filter for port with given configuration
 *
 * @param[in] regBase:   GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] width:  The digital filter width
 * @return None
 */
#if (CONFIG_GPIO_SUPPORT_INDEPENDENT_DFL == 1U)
void GPIO_SetDigitalFilterRUNWidth(GPIO_Type* regBase,
                                   uint8_t width);
#else
void GPIO_SetDigitalFilterWidth(GPIO_Type* regBase,
                                uint8_t width);
#endif

/*!
 * @brief Enables digital filter for the given digital pin in run mode
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return None
 */
void GPIO_EnablePinDigitalFilterRUN(GPIO_Type* regBase,
                                    uint32_t pinNum);

/*!
 * @brief Disables digital filter for the given digital pin in run mode
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return None
 */
void GPIO_DisablePinDigitalFilterRUN(GPIO_Type* regBase,
                                     uint32_t pinNum);

/*!
 * @brief Enables digital filter for the given pin in lowpower mode
 *
 * @note  Only one pin can be configured to as digital filter wakeup pin simultaneously
 *        in lowpower mode, and only the pin takes effect which is the last configured
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] width:  The digital filter width for lowpower mode
 * @return None
 */
#if (CONFIG_GPIO_SUPPORT_INDEPENDENT_DFL == 1U)
void GPIO_EnablePinDigitalFilterLP(GPIO_Type* regBase,
                                   uint32_t pinNum,
                                   uint8_t width);
#else
void GPIO_EnablePinDigitalFilterLP(GPIO_Type* regBase,
                                   uint32_t pinNum);
#endif

/*!
 * @brief Disables digital filter for the given port in lowpower mode
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @return None
 */
void GPIO_DisablePinDigitalFilterLP(GPIO_Type* regBase);

/*!
 * @brief Writes a pin for the given pin with a given value
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @param[in] pinLevel: Pin level to be written
 *        - GPIO_PIN_LEVEL_LOW: corresponding pin is set to LOW
 *        - GPIO_PIN_LEVEL_HIGH: corresponding pin is set to HIGH
 * @return None
 */
void GPIO_WritePin(GPIO_Type* regBase,
                   uint32_t pinNum,
                   gpio_pin_level_t pinLevel);

/*!
 * @brief Writes all pins configured as output with the values given in
 *        the parameter pins, '0' represents LOW, '1' represents HIGH
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinMsk: Each bit represents one pin(LSB is pin 0, MSB is pin 31)
 * For each bit:
 *        - 0: corresponding pin is set to LOW
 *        - 1: corresponding pin is set to HIGH
 * @return None
 */
void GPIO_WritePins(GPIO_Type* regBase,
                    uint32_t pinMsk);

/*!
 * @brief Gets the current output for the given port, Only pins
 *        that are configured as output will have meaningful values
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @return GPIO outputs. Each bit represents one pin (LSB is pin 0, MSB is pin 31)
 * For each bit:
 *        - 0: corresponding pin is set to LOW
 *        - 1: corresponding pin is set to HIGH
 */
uint32_t GPIO_GetPinsOutput(const GPIO_Type* regBase);

/*!
 * @brief Writes pins to logic HIGH listed in parameter pins (bits that are '1')
 *        Pins corresponding to '0' will be unaffected
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinMsk: Each bit represents one pin (LSB is pin 0, MSB is pin 31)
 * For each bit:
 *        - 0: corresponding pin is unaffected
 *        - 1: corresponding pin is set to HIGH
 * @return None
 */
void GPIO_SetPins(GPIO_Type* regBase,
                  uint32_t pinMsk);

/*!
 * @brief Writes pins to logic LOW listed in parameter pins (bits that are '1')
 *        Pins corresponding to '0' will be unaffected
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinMsk: Each bit represents one pin (LSB is pin 0, MSB is pin 31)
 * For each bit:
 *        - 0: corresponding pin is unaffected
 *        - 1: corresponding pin is set to LOW
 * @return None
 */
void GPIO_ResetPins(GPIO_Type* regBase,
                    uint32_t pinMsk);

/*!
 * @brief Toggles pins output listed in parameter pins (bits that are '1')
 *        Pins corresponding to '0' will be unaffected
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinMsk: Each bit represents one pin (LSB is pin 0, MSB is pin 31)
 * For each bit:
 *        - 0: corresponding pin is unaffected
 *        - 1: corresponding pin is toggled
 * @return None
 */
void GPIO_TogglePins(GPIO_Type* regBase,
                     uint32_t pinMsk);

/*!
 * @brief Reads input pin for the given pin
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @param[in] pinNum: The pin number, Valid range:0 - 31
 * @return GPIO pin input
 *        - GPIO_PIN_LEVEL_LOW: corresponding pin is LOW
 *        - GPIO_PIN_LEVEL_HIGH: corresponding pin is HIGH
 */
gpio_pin_level_t GPIO_ReadPin(const GPIO_Type* regBase,
                              uint32_t pinNum);

/*!
 * @brief Reads input pins for a given port, Only pins configured as input
 *        will have meaningful values
 *
 * @param[in] regBase: GPIO register base pointer (GPIOA, GPIOB, GPIOC, etc.)
 * @return GPIO inputs. Each bit represents one pin (LSB is pin 0, MSB is pin 31)
 * For each bit:
 *        - 0: corresponding pin is read as LOW
 *        - 1: corresponding pin is read as HIGH
 */
uint32_t GPIO_ReadPins(const GPIO_Type* regBase);


#if defined(__cplusplus)
}
#endif

/*! @} */

#endif /* GPIO_DRV_H */

/*******EOF********************************************************************/
